using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Windows.Forms;

using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.PolicyInjection;
using System.Threading;
using EntLibContrib.PolicyInjection.CallHandlers;

namespace EntLibContrib.PolicyInjection.Tests
{
    [TestClass]
    public class OneWayCallHandlerFixture
    {
        [TestMethod, DeploymentItem("OneWayCallHandler.config")]
        public void OneWay_With_Config_Should_Not_Cause_Deadlock()
        {
            IConfigurationSource configurationSource = new FileConfigurationSource("OneWayCallHandler.config");

            OneWayFoo foo = Microsoft.Practices.EnterpriseLibrary.PolicyInjection.PolicyInjection.Create<OneWayFoo>(configurationSource);

            AutoResetEvent start = new AutoResetEvent(false);

            foo.Do(start);
            start.Set();

            bool signaled = foo.Completed.WaitOne(1000, false);

            Assert.IsTrue(signaled, "Deadlock occured");
        }

        [TestMethod]
        public void OneWay_With_Attributes_Should_Not_Cause_Deadlock()
        {
            OneWayFooWithAttributes foo = Microsoft.Practices.EnterpriseLibrary.PolicyInjection.PolicyInjection.Create<OneWayFooWithAttributes>();

            AutoResetEvent start = new AutoResetEvent(false);

            foo.Do(start);
            start.Set();

            bool signaled = foo.Completed.WaitOne(1000, false);

            Assert.IsTrue(signaled, "Deadlock occured");
        }
    }

    public class OneWayFoo : MarshalByRefObject
    {
        private AutoResetEvent completed = new AutoResetEvent(false);

        public void Do(WaitHandle start)
        {
            bool signaled = start.WaitOne(100, false);

            Assert.IsTrue(signaled, "Deadlock occured");

            Thread.Sleep(100); // Simulate lengthy operation.

            completed.Set();
        }

        public WaitHandle Completed
        {
            get { return completed; }
        }
    }

    [OneWayCallHandler]
    public class OneWayFooWithAttributes : MarshalByRefObject
    {
        private AutoResetEvent completed = new AutoResetEvent(false);

        public void Do(WaitHandle start)
        {
            bool signaled = start.WaitOne(100, false);

            Assert.IsTrue(signaled, "Deadlock occured");

            Thread.Sleep(100); // Simulate lengthy operation.

            completed.Set();
        }

        public WaitHandle Completed
        {
            get { return completed; }
        }
    }
}

